package com.ysstech.common.realm;

import com.alibaba.fastjson.JSONArray;
import com.ysstech.common.cache.RedisCacheManager;
import com.ysstech.common.entity.Menu;
import com.ysstech.common.entity.Region;
import com.ysstech.common.entity.Role;
import com.ysstech.common.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义Realm
 */

@Slf4j
public class YssRealm extends AuthorizingRealm {
    @Autowired
    private RedisCacheManager redisCacheManager;

    /**
     * 重写的权限验证的方法，每次去取缓存里用户的信息来判断
     *
     * @param principals
     * @param permission
     * @return
     */
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        String msg = "没有找到权限编码 [" + permission + "]";
        try {
            String token = (String) principals.getPrimaryPrincipal();
            //根据用户名查询出用户记录
            String json = (String) redisCacheManager.getCache(token);
            User user = JSONArray.parseObject(json, User.class);
            if (null == user) {
                return false;
            }
            List<Role> roleList = user.getRoles();
            Map<String, String> map = new HashMap<>();
            for (Role role : roleList) {
                if (null == role) {
                    continue;
                }
                List<Menu> menuList = role.getListMenu();
                for (Menu menu : menuList) {
                    map.put(menu.getPermissions(), menu.getPermissions());
                }
                List<Region> regionList = role.getListRegion();
                for (Region region : regionList) {
                    map.put(region.getPermissions(), region.getPermissions());
                }
            }
            if (!map.containsKey(permission)) {
                return false;
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new UnauthorizedException(msg);
        }
        return true;
    }

    /**
     * 权限检查 shiro的默认处理 shiro会缓存，第一次进来调用
     * 如果要走这里，就需要 isPermitted 注释这个方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      /*  try {
            String token = (String) principals.getPrimaryPrincipal();
            //根据用户名查询出用户记录
            String json = (String) redisCacheManager.getCache(token);
            User user = JSONArray.parseObject(json, User.class);
            if (null == user) {
                throw new BusinessException("用户没有获取登录授权！");
            }
            List<Role> roleList = user.getRoles();
            Set<String> roles = new HashSet<>();
            for (Role role : roleList) {
                if (null == role) {
                    continue;
                }
                roles.add(role.getId());
                List<Menu> menuList = role.getListMenu();
                for (Menu menu : menuList) {
                    info.addStringPermission(menu.getPermissions()); // 菜单权限
                }
                List<Region> regionList = role.getListRegion();
                for (Region region : regionList) {
                    info.addStringPermission(region.getPermissions()); // 按钮权限
                }
            }
            info.setRoles(roles);
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new UnauthorizedException("你没有该页面的权限，请联系管理员！");
        }*/
        return info;
    }

    /**
     * 登录认证，使用token
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String usertoken = (String) token.getPrincipal();
        String json = (String) redisCacheManager.getCache(usertoken);
        User user = JSONArray.parseObject(json, User.class);
        if (user != null) {
            AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(usertoken, user.getId(), "ysstech");
            return authcInfo;
        } else {
            return null;
        }
    }

}
